package cc.rengu.igas.opms.core.service.trans.quickpay;

import cc.rengu.igas.channel.ncqs.facade.response.NcqsAgreePaySignAcqResponse;
import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.*;
import cc.rengu.igas.opms.common.util.ParameterUtil;
import cc.rengu.igas.opms.core.model.SignCardInfoBean;
import cc.rengu.igas.opms.core.realize.SignCardInfoService;
import cc.rengu.igas.opms.core.realize.impl.SignCardInfoServiceImpl;
import cc.rengu.igas.opms.core.service.base.PayService;
import cc.rengu.igas.opms.facade.request.FisrtCardSignAndPayRequest;
import cc.rengu.igas.opms.facade.response.FisrtCardSignAndPayResponse;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.constant.UserSessionConstant;
import cc.rengu.igas.share.common.enums.UserPayAuthTypeEnum;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.PlatMchntInfo;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MsgTemplateCfgMapper;
import cc.rengu.oltp.service.common.dao.NonFinanceTxnMapper;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MsgTemplateCfgMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.NonFinanceTxnMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.common.enums.LimitAcctTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SmsService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SmsServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 银行卡首次签约并支付
 * 签约通道根据报文头中的业务类型进行判断
 * 当前交易先签约后进行支付，支付结果不影响签约结果
 * Created by fyp on 2020/4/3.
 * modify by wangcheng 2021-09-13
 */
public class FisrtCardSignAndPayService extends PayService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest = new FisrtCardSignAndPayRequest();
        ConvertUtil.convertOutput(fisrtCardSignAndPayRequest);
        String orderAmt = AmountUtil.checkAmt(fisrtCardSignAndPayRequest.getOrderAmt(), 2, false);
        fisrtCardSignAndPayRequest.setOrderAmt(orderAmt);
        //去掉参数的空格，并对金额进行格式化
        ParameterUtil.paramertTrimAndFormatAmt(fisrtCardSignAndPayRequest);
        return fisrtCardSignAndPayRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest = (FisrtCardSignAndPayRequest) request;
        String instId = fisrtCardSignAndPayRequest.getHeader().getInstId();
        String txnNum = fisrtCardSignAndPayRequest.getHeader().getTxnNum();
        String bizType = fisrtCardSignAndPayRequest.getHeader().getBizType();
        String userId = fisrtCardSignAndPayRequest.getUserId();
        String payAcctNo = fisrtCardSignAndPayRequest.getAcctNo();
        String certType = fisrtCardSignAndPayRequest.getCertType();
        String certNo = fisrtCardSignAndPayRequest.getCertNo();
        String signTokenType = fisrtCardSignAndPayRequest.getSignTokenType();
        String smsCode = fisrtCardSignAndPayRequest.getSmsCode();
        String smsVerifySeqNum = fisrtCardSignAndPayRequest.getSmsVerifySeqNum();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String isBuyCouponTrans = AppParamConstant.NO;

        //获取三要素验证结果，验三要素校验接口是否调用成功,防止越过三要素交易直接进行签约
        UserService userService = new UserServiceImpl();
        String authenticationFinishFlag = userService.getUserSessionValue(UserSessionConstant.AUTHENTICATION_FINISH_FLAG);
        if (!AppParamConstant.YES.equals(authenticationFinishFlag)) {
            rglog.info("交易流程跳跃，三要素校验接口未完成.<{}>", authenticationFinishFlag);
            throw new BizException(RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespCode(), RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespDesc());
        }

        //获取用户标识、签约类型以及用户所属主体等信息
        String signType = userService.getUserSignType();
        String signInst = userService.getUserSignInst();
        String userInst = instId;
        if (SignTypeEnum.PLAT_CLASS_SIGN.getSignTypeCode().equals(platMchntInfo.getSignType())) {
            userInst = platMchntInfo.getPlatMchntNo();
        }
        //授信平台商户必须上送用户标识
        if (null != platMchntInfo && OpmsParamConstant.STR_ONE.equals(platMchntInfo.getGrantCreditFlag())) {
            if (StringUtil.isEmptyOrNull(userId)) {
                rglog.error("授信平台商户使用接口上送的用户标识,但接口没有上送userId:<{}>", userId);
                throw new BizException(RespCodeEnum.PARAM_ERROR.getRespCode(), RespCodeEnum.PARAM_ERROR.getRespDesc());
            }
        }

        //用户校验是否存在
        UserInfo userInfo = userService.getUserInfoByCertInfo(instId, userInst, certType, certNo);
        if (userInfo != null && OpmsParamConstant.OPR_TYP_NO_OPER.equals(userInfo.getUserStatus())) {
            rglog.error("用户<{}>已存在，请登录后支付", userInfo.getUserId());
            throw new BizException(RespCodeEnum.USER_EXIT_ERROR.getRespCode(), RespCodeEnum.USER_EXIT_ERROR.getRespDesc());
        }
        if (null != userInfo && !StringUtil.isEmptyOrNull(userId) && !userInfo.getUserId().equals(userId)) {
            rglog.error("接口上送的userId:<{}>与数据库中保存的userId:<{}>不一致！", userId, userInfo.getUserId());
            throw new BizException(RespCodeEnum.USER_INFO_MISMATCH.getRespCode(), RespCodeEnum.USER_INFO_MISMATCH.getRespDesc());
        }

        //检查签约信息
        SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
        List<SignAcctInfo> signAcctInfoList = signAcctInfoMapper.selectSignAcctInfoByCertInfo(instId, certType, certNo);
        if (null != signAcctInfoList && !signAcctInfoList.isEmpty()) {
            signAcctInfoList = signAcctInfoList.stream().filter(item -> item.getSignType().equals(signType) && item.getSignInst().equals(signInst)).collect(Collectors.toList());
            //判断是否已经签约该银行卡
            Optional<SignAcctInfo> signAcctInfoOpt = signAcctInfoList.stream().filter(item -> item.getSignAcctNo().equals(payAcctNo) && AppParamConstant.YES.equals(item.getSignStatus())).findFirst();
            if (signAcctInfoOpt.isPresent()) {
                if (null == userInfo || !"00".equals(userInfo.getUserStatus())) {
                    rglog.error("签约关系存在但是用户不存在或用户已注销，数据错误。instId:<{}>,userInst:<{}>,userId:<{}>,signInst:<{}>,signToken:<{}>",
                            fisrtCardSignAndPayRequest.getHeader().getInstId(), userInst, userInfo == null ? "空" : userInfo.getUserId(), signAcctInfoOpt.get().getSignInst(), signAcctInfoOpt.get().getSignInst());
                    throw new BizException(RespCodeEnum.USER_INFO_MISMATCH.getRespCode(), RespCodeEnum.USER_INFO_MISMATCH.getRespDesc());
                }
            }
        }

        //校验短信流水号
        NonFinanceTxn nonFinanceTxn;
        if (PassTypeEnum.BANK_SIAN.getPassCode().equals(signTokenType)) {
            rglog.info("本行快捷签约，校验验证码:<{}>", signTokenType);
            SmsService smsService = new SmsServiceImpl();
            smsService.verifySmsCode(instId, SmsTypeEnum.CARD_SIGN.getSmsType(), smsCode, smsVerifySeqNum, fisrtCardSignAndPayRequest.getPhoneNo());
        } else {
            rglog.info("非本行快捷签约，验证码验证流水号：<{}>", smsVerifySeqNum);
            NonFinanceTxnMapper nonFinanceTxnMapper = new NonFinanceTxnMapperImpl();
            nonFinanceTxn = nonFinanceTxnMapper.selectNonFinanceTxnInfoByPrimaryKey(instId, smsVerifySeqNum);
            if (nonFinanceTxn == null) {
                rglog.info("非金融流水表中无该请求短信验证码交易，instId:<{}>,smsVerifySeqNum:<{}>", instId, smsVerifySeqNum);
                throw new BizException(RespCodeEnum.VERIFICATION_CODE_INVALID.getRespCode(), RespCodeEnum.VERIFICATION_CODE_INVALID.getRespDesc());
            }
            GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_NON_FINANCE_TXN, nonFinanceTxn);
            GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_CHANNEL_RELATION_KEY, nonFinanceTxn.getChannelOrderId());
        }

        //获取银行卡签约时需要的数据
        SignCardInfoService cardBinCheckService = new SignCardInfoServiceImpl();
        SignCardInfoBean signCardInfo = cardBinCheckService.getSignCardInfo(instId, payAcctNo, signTokenType);
        GlobalTransUtil.setCacheValue(TransCacheConstant.SIGN_CARD_INFO, signCardInfo);
        rglog.info("绑卡签约的账户类型,acctType:<{}>", signCardInfo.getAcctType());

        //获取订单信息
        OrderService orderService = new OrderServiceImpl();
        OrderInfo orderInfo = orderService.selectOrderInfoByUserOrderId(instId, fisrtCardSignAndPayRequest.getUserOrderId());
        if (null == orderInfo) {
            rglog.error("订单信息不存在!");
            throw new BizException(RespCodeEnum.ORDER_NOEXIT.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        }
        UserOrderInfo userOrderInfo = orderInfo.getUserOrderInfo();
        userOrderInfo.setSysSeqNum(sysSeqNum);
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setTxnNum(txnNum);
        userOrderInfo.setBizType(bizType);
        userOrderInfo.setUserId(userId);
        userOrderInfo.setOrderDesc(fisrtCardSignAndPayRequest.getOrderDesc());
        List<MchntOrderInfo> mchntOrderInfoList = orderInfo.getMchntOrderInfoList();
        GlobalTransUtil.setCacheValue(TransCacheConstant.MCHNT_ORDER_INFO_LIST, mchntOrderInfoList);
        List<MchntOrderDetail> mchntOrderDetailList = orderInfo.getMchntOrderDetailList();
        if (null != mchntOrderDetailList && !mchntOrderDetailList.isEmpty()) {
            mchntOrderDetailList.forEach(item -> item.setSysSeqNum(sysSeqNum));
        }

        //购买卡券不支持使用优惠券
        if ("00".equals(mchntOrderInfoList.get(0).getBizSceneType()) || "02".equals(mchntOrderInfoList.get(0).getBizSceneType())) {
            isBuyCouponTrans = AppParamConstant.YES;
            GlobalTransUtil.setCacheValue(TransCacheConstant.BUY_COUPON_TRANS_FLAG, AppParamConstant.YES);
            if (fisrtCardSignAndPayRequest.getCouponInfo() != null && fisrtCardSignAndPayRequest.getCouponInfo().getDiscountId() != null) {
                rglog.error("购买卡券交易不支持使用卡券");
                throw new BizException(RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespCode(), RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespDesc());
            }
        }
        //判断是否有上送卡卷,若有上送，则将优惠卷放到交易缓存中
        if (fisrtCardSignAndPayRequest.getCouponInfo() != null && fisrtCardSignAndPayRequest.getCouponInfo().getDiscountId() != null) {
            GlobalTransUtil.setCacheValue(TransCacheConstant.COUPON_INFO, fisrtCardSignAndPayRequest.getCouponInfo());
        }
        //合并订单支付，不能合并特殊费率跟非特殊费率，不能合并d0清算跟非d0清算
        if (mchntOrderInfoList.size() > 1) {
            List<MchntOrderInfo> mchntOrderInfoSpFeeList = mchntOrderInfoList.stream().filter(item -> "0".equals(item.getFeeInputMode())).collect(Collectors.toList());
            if (!mchntOrderInfoSpFeeList.isEmpty() && mchntOrderInfoSpFeeList.size() != mchntOrderInfoList.size()) {
                rglog.error("合并订单中存在特殊费率跟非特殊费率的订单，拒绝交易");
                updateOrderInfoFail(userOrderInfo, mchntOrderInfoList);
                throw new BizException(RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespCode(), RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespDesc());
            }
            List<MchntOrderInfo> mchntOrderInfoD0List = mchntOrderInfoList.stream().filter(item -> AppParamConstant.YES.equals(item.getRealSettleFlag())).collect(Collectors.toList());
            if (!mchntOrderInfoD0List.isEmpty() && mchntOrderInfoD0List.size() != mchntOrderInfoList.size()) {
                rglog.error("合并订单中存在d0清算跟非d0清算的订单，拒绝交易");
                updateOrderInfoFail(userOrderInfo, mchntOrderInfoList);
                throw new BizException(RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespCode(), RespCodeEnum.ORDER_NOT_ALLOW_PAY.getRespDesc());
            }
            //无卡快捷支付不支持合并支付
            if ("01".equals(bizType)) {
                rglog.error("合并支付不支持银联无卡快捷支付");
                throw new BizException(RespCodeEnum.MCHNT_NO_PERMISSION.getRespCode(), RespCodeEnum.MCHNT_NO_PERMISSION.getRespDesc());
            }
        }

        //商户权限及限额检查
        MchntService mchntService = new MchntServiceImpl();
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
            /*获取商户基本信息表*/
            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntOrderInfo.getMchntNo());
            /*判断商户是否是独立清算的门店商户*/
            if ("11".equals(mchntInfo.getMchntType()) && AppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                rglog.debug("非独立维护资料的门店商户商户订单表记录其连锁商户号");
                mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
                mchntInfo = mchntService.getMchntInfo(instId, mchntInfo.getChainMchntNo());
            }
            /* 商户交易权限检查 */
            boolean checkResult = mchntService.checkMchntAuth(instId, mchntOrderInfo.getMchntNo(), null, txnNum, bizType, signCardInfo.getAcctType());
            if (!checkResult) {
                rglog.error("商户<{}>无此交易权限!", mchntOrderInfo.getMchntNo());
                throw new BizException(RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespCode(), RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespDesc());
            }
            /* 商户限额校验 */
            int limitFlag = mchntService.checkMchntTransLimit(instId, mchntOrderInfo.getRealSettleAmt(), LimitAcctTypeEnum.ALL, mchntOrderInfo.getMchntNo(), null, txnNum);
            if (limitFlag == 2 || limitFlag == 3) {
                rglog.error("商户金额超限");
                throw new BizException(RespCodeEnum.MCHNT_AMT_OVER.getRespCode(), RespCodeEnum.MCHNT_AMT_OVER.getRespDesc());
            } else if (limitFlag == 1) {
                rglog.debug("商户贷记卡超限，交易上送不支持贷记卡标识");
                xmlTreeUtil.setXmlTreeStringValue("limitPay", "no_credit");
            }
            /* 商户订单信息赋值 */
            mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
            mchntOrderInfo.setTxnNum(txnNum);
            mchntOrderInfo.setBizType(bizType);
            mchntOrderInfo.setSysSeqNum(sysSeqNum);
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
            mchntOrderInfo.setMchntDiscountFee("0.00");
            mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
            mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            if (fisrtCardSignAndPayRequest.getCouponInfo() != null && fisrtCardSignAndPayRequest.getCouponInfo().getDiscountId() != null) {
                mchntOrderInfo.setRealSettleFlag(AppParamConstant.NO);
            } else {
                String realSettleFlag = mchntService.getRealSettleFlag(mchntInfo.getMchntNo(), txnInfo.getSrcTxnAuthCfg().getBizProdCode(), mchntOrderInfo.getBizSceneType(), mchntOrderInfo.getRealSettleAmt());
                mchntOrderInfo.setRealSettleFlag(realSettleFlag);
                if (AppParamConstant.YES.equals(mchntOrderInfo.getRealSettleFlag())) {
                    mchntOrderInfo.setRealSettleType("99");
                }
            }
        }

        //非购买卡卷交易计算商户手续费
        if (AppParamConstant.NO.equals(isBuyCouponTrans)) {
            String feeType;
            if (AcctTypeEnum.BANK_CREDIT.getAcctType().equals(signCardInfo.getAcctType())) {
                feeType = FeeTypeEnum.BANK_CR_CARD.getFeeType();
            } else if (AcctTypeEnum.BANK_DEBIT.getAcctType().equals(signCardInfo.getAcctType())) {
                feeType = FeeTypeEnum.BANK_DR_CARD.getFeeType();
            } else if (AcctTypeEnum.OTHER_DEBIT.getAcctType().equals(signCardInfo.getAcctType())) {
                feeType = FeeTypeEnum.OTHER_BANK_DR_CARD.getFeeType();
            } else {
                feeType = FeeTypeEnum.OTHER_BANK_CR_CARD.getFeeType();
            }
            mchntService.calcMchntFee(mchntOrderInfoList, feeType);
        }

        //更新订单信息
        if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList)) {
            rglog.error("更新订单信息失败");
            throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
        }

        //调用通道接口
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(fisrtCardSignAndPayRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, orderInfo, channelCallCfg.getBizScene(), request);

        //将三要素校验步骤重置为空
        userService.setUserSessionValue(UserSessionConstant.AUTHENTICATION_FINISH_FLAG, AppParamConstant.NO);

        //拼装应答报文
        FisrtCardSignAndPayResponse fisrtCardSignAndPayResponse = new FisrtCardSignAndPayResponse();
        SignAcctInfo signAcctInfo = (SignAcctInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_ACCT_INFO);
        if (null != signAcctInfo) {
            fisrtCardSignAndPayResponse.setSignToken(signAcctInfo.getSignToken());
            fisrtCardSignAndPayResponse.setUserId(signAcctInfo.getUserId());
            fisrtCardSignAndPayResponse.setUserName(signAcctInfo.getCardHoldName());
        }
        fisrtCardSignAndPayResponse.setHeader(fisrtCardSignAndPayRequest.getHeader());
        fisrtCardSignAndPayResponse.setUserId(userOrderInfo.getUserId());
        fisrtCardSignAndPayResponse.setUserName(fisrtCardSignAndPayRequest.getCardHoldName());
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByPrimaryKey(instId, sysSeqNum);
        if (null != userOrderInfo) {
            fisrtCardSignAndPayResponse.setDiscountAmt(userOrderInfo.getRealDiscountAmt());
            fisrtCardSignAndPayResponse.setOrderAmt(userOrderInfo.getOrderAmt());
            fisrtCardSignAndPayResponse.setActualAmt(userOrderInfo.getRealPayAmt());
        }
        BizResponse<FisrtCardSignAndPayResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setResult(fisrtCardSignAndPayResponse);
        String userPayLimitExceededFlag = (String) GlobalTransUtil.getCacheValue(TransCacheConstant.USER_LIMIT_EXCEEDED);
        if (!StringUtil.isEmptyOrNull(userPayLimitExceededFlag) && AppParamConstant.YES.equals(userPayLimitExceededFlag)) {
            //用户限额超限返回特殊错误码
            bizResponse.setRespCode(RespCodeEnum.OVER_LIMIT_AMT.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.OVER_LIMIT_AMT.getRespDesc());
        } else {
            //交易成功更新商户累计限额
            mchntService.updateMchntTransLimit(mchntOrderInfoList);
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        }
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        FisrtCardSignAndPayResponse fisrtCardSignAndPayResponse = (FisrtCardSignAndPayResponse) ((BizResponse) response).getResult();
        ConvertUtil.convertInput(fisrtCardSignAndPayResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest = (FisrtCardSignAndPayRequest) request;
        String bizType = fisrtCardSignAndPayRequest.getHeader().getBizType();
        SignCardInfoBean signCardInfo = (SignCardInfoBean) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_CARD_INFO);
        if (null != signCardInfo) {
            String bizScene;
            if ("00".equals(bizType) && AcctTypeEnum.BANK_DEBIT.getAcctType().equals(signCardInfo.getAcctType())) {
                /* 本行借记卡签约并支付场景 */
                bizScene = "00";
            } else if ("00".equals(bizType) && AcctTypeEnum.BANK_CREDIT.getAcctType().equals(signCardInfo.getAcctType())) {
                /* 本行贷记卡签约并支付场景 */
                bizScene = "01";
            } else if ("01".equals(bizType)) {
                /* 银联无卡快捷签约并支付场景 */
                bizScene = "02";
            } else {
                rglog.error("不支持的业务分类:{}", bizType);
                throw new BizException(RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespCode(), RespCodeEnum.NOT_SURP_TRANS_TYPE_ERROR.getRespDesc());
            }
            List<ChannelCallCfg> channelCallCfgs = channelCallCfgList.stream().filter(item -> item.getBizScene().equals(bizScene)).collect(Collectors.toList());
            if (channelCallCfgs.size() > 1) {
                Optional<ChannelCallCfg> channelCallCfgOpt;
                if ("0103".equals(channelCallCfgList.get(0).getCallIndex())) {
                    List<MchntOrderInfo> mchntOrderInfoList = (List<MchntOrderInfo>) GlobalTransUtil.getCacheValue(TransCacheConstant.MCHNT_ORDER_INFO_LIST);
                    if ("00".equals(Objects.requireNonNull(mchntOrderInfoList).get(0).getBizSceneType()) || "01".equals(mchntOrderInfoList.get(0).getBizSceneType())
                            || "02".equals(mchntOrderInfoList.get(0).getBizSceneType()) || "0".equals(mchntOrderInfoList.get(0).getFeeInputMode())) {
                        /* 担保支付、购买卡卷、特殊计算商户不给商户进行实时入账及虚拟账记账，只推送交易结果通知 */
                        rglog.info("订单全为购买卡券或担保支付或特殊计费商户的交易，不给商户入账，直接推送通知");
                        channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getCallChannelId().equals("LOCAL")).findFirst();
                    } else {
                        if (AppParamConstant.YES.equals(Objects.requireNonNull(mchntOrderInfoList).get(0).getRealSettleFlag())) {
                            /* 商户D0清算场景 */
                            channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getCallChannelId().equals(ChannelEnum.ESB.getChannelType())).findFirst();
                        } else {
                            /* 商户非D0清算场景 */
                            channelCallCfgOpt = channelCallCfgList.stream().filter(item -> item.getCallChannelId().equals(ChannelEnum.ACCT.getChannelType())).findFirst();
                        }
                    }
                    return channelCallCfgOpt.orElse(null);
                }
            } else {
                return channelCallCfgs.stream().findFirst().orElse(null);
            }
        }
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest = (FisrtCardSignAndPayRequest) request;
        UserService userService = new UserServiceImpl();
        String instId = fisrtCardSignAndPayRequest.getHeader().getInstId();
        String userId = fisrtCardSignAndPayRequest.getUserId();
        String txnNum = fisrtCardSignAndPayRequest.getHeader().getTxnNum();
        String orderAmt = fisrtCardSignAndPayRequest.getOrderAmt();
        /* 签约后再调用支付前营销时先检查是否超限，若超限，则只完成签约流程，后结果流程不再继续，直接结束交易 */
        if ("0101".equals(channelCallCfg.getCallIndex())) {
            UserPayAuthTypeEnum userPayAuthTypeEnum = userService.getUserPayAuthType(instId, userId, orderAmt, LimitTypeEnum.CASHIER.getLimitType());
            if (UserPayAuthTypeEnum.PASSWORD_UKEY.equals(userPayAuthTypeEnum)) {
                rglog.warn("线上收银台支付金额超限，不支持密码+UKEY的认证方式！");
                throw new BizException(RespCodeEnum.LIMIT_OVER_NO_PAY.getRespCode(), RespCodeEnum.LIMIT_OVER_NO_PAY.getRespDesc());
            }
        }
        /* 营销后支付前调用前检查用户支付限额，若用户限额超限，则返回检查失败 */
        if ("0102".equals(channelCallCfg.getCallIndex())) {
            String realPayAmt = orderInfo.getUserOrderInfo().getRealPayAmt();
            boolean checkResult = userService.checkUserTransLimit(instId, userId, txnNum, realPayAmt, LimitTypeEnum.CASHIER.getLimitType());
            if (!checkResult) {
                rglog.error("用户支付限额超限!");
                GlobalTransUtil.setCacheValue(TransCacheConstant.USER_LIMIT_EXCEEDED, AppParamConstant.YES);
                return CheckResultEnum.FAILURE;
            }
        }
        /* 调用营销前生成营销用户集合(手机号、卡号、微信openId、支付宝userId等)，营销基于此信息判断用户是否可以享受营销 */
        if (ChannelEnum.MOMP.getChannelType().equals(channelCallCfg.getCallChannelId()) && "P01MO003".equals(channelCallCfg.getCallChannelTxn())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("phoneNo", xmlTreeUtil.getXmlTreeStringValue("phoneNo"));
            jsonObject.put("cardNo", xmlTreeUtil.getXmlTreeStringValue("acctNo"));
            /* 将用户信息放到交易缓存，同时将营销用户信息放到用户缓存中，便于付成功后优惠券信息查询和优惠券领取的接口调用时使用 */
            rglog.debug("营销用户信息:{}", jsonObject.toJSONString());
            GlobalTransUtil.setCacheValue(TransCacheConstant.MOMP_USER_INFO, jsonObject.toJSONString());
            userService.setUserSessionValue(UserSessionConstant.MOMP_USER_ID, jsonObject.toJSONString());
        }
        /* 本行借记卡签约成功短信通知 */
        if (ChannelEnum.SMPS.getChannelType().equals(channelCallCfg.getCallChannelId())) {
            if ("00450000000E01".equals(channelCallCfg.getCallChannelTxn())) {
                MsgTemplateCfgMapper msgTemplateCfgMapper = new MsgTemplateCfgMapperImpl();
                MsgTemplateCfg msgTemplateCfg = msgTemplateCfgMapper.selectMsgTemplateCfgByTemplateType(instId, TemplateTypeEnum.SMS_FAST_PAYMENT_SIGN_SUCC.getTemplateType());
                if (null == msgTemplateCfg) {
                    msgTemplateCfg = msgTemplateCfgMapper.selectMsgTemplateCfgByTemplateType(AppParamConstant.DEFAULT_INSTID, TemplateTypeEnum.SMS_FAST_PAYMENT_SIGN_SUCC.getTemplateType());
                    if (null == msgTemplateCfg) {
                        rglog.error("未配置短信发送模板!");
                        throw new BizException(RespCodeEnum.NOT_CONF_MSG_TEMPLATE.getRespCode(), RespCodeEnum.NOT_CONF_MSG_TEMPLATE.getRespDesc());
                    }
                }
                SignAcctInfo signAcctInfo = (SignAcctInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_ACCT_INFO);
                GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_TEMPLATE_CODE, msgTemplateCfg.getTemplateCode());
                if (null != signAcctInfo && !StringUtil.isEmptyOrNull(msgTemplateCfg.getTemplateDesc())) {
                    String lastAcctNo = signAcctInfo.getSignAcctNo().substring(signAcctInfo.getSignAcctNo().length() - 4);
                    String smsContent = parseSmsTemplateInfo(msgTemplateCfg.getTemplateDesc(), lastAcctNo);
                    GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_CONTENT, smsContent);
                    List<String> phoneNoList = Collections.singletonList(signAcctInfo.getReserveMobileNo());
                    GlobalTransUtil.setCacheValue(TransCacheConstant.SMS_PHONE_NO_LIST, phoneNoList);
                }
            }
        }
        /* 商户实时入账时基于按照商户逐个调用 */
        if (ChannelEnum.ESB.getChannelType().equals(channelCallCfg.getCallChannelId())) {
            if ("baffle".equals(channelCallCfg.getCallChannelTxn())) {
                List<String> realAcctMchntNoList = (List<String>) GlobalTransUtil.getCacheValue(TransCacheConstant.REAL_ACCT_MCHNT_NO_LIST);
                if (null == realAcctMchntNoList || realAcctMchntNoList.isEmpty()) {
                    realAcctMchntNoList = new ArrayList<>();
                }
                for (MchntOrderInfo mchntOrderInfo : orderInfo.getMchntOrderInfoList()) {
                    if (!realAcctMchntNoList.contains(mchntOrderInfo.getMchntNo())) {
                        realAcctMchntNoList.add(mchntOrderInfo.getMchntNo());
                        GlobalTransUtil.setCacheValue(TransCacheConstant.REAL_ACCT_MCHNT_NO, mchntOrderInfo.getMchntNo());
                        break;
                    }
                }
                if (realAcctMchntNoList.size() == orderInfo.getMchntOrderInfoList().size()) {
                    return CheckResultEnum.PASSED;
                } else {
                    return CheckResultEnum.REPEAT;
                }
            }
        }
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest = (FisrtCardSignAndPayRequest) request;
        //调用营销失败且客户使用卡卷时，则直接拒绝交易
        if (ChannelEnum.MOMP.getChannelType().equals(channelCallCfg.getCallChannelId()) && !TransStatusEnum.TRANS_SUCC.equals(transStatusEnum)) {
            if ("P01MO003".equals(channelCallCfg.getCallChannelTxn()) && null != fisrtCardSignAndPayRequest.getCouponInfo() &&
                    (null != fisrtCardSignAndPayRequest.getCouponInfo().getDiscountId() || null != fisrtCardSignAndPayRequest.getCouponInfo().getDiscountAmt())) {
                rglog.error("用户支付时有使用卡卷，调用营销失败，则整个交易失败!");
                throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
            }
        }
        if (TransStatusEnum.TRANS_SUCC.equals(transStatusEnum) && null != channelResponse) {
            //调用通道签约成功后，登记或者更新用户签约信息
            if (("00".equals(channelCallCfg.getBizScene()) && "0001".equals(channelCallCfg.getCallIndex())) ||
                    ("01".equals(channelCallCfg.getBizScene()) && "0000".equals(channelCallCfg.getCallIndex())) ||
                    ("02".equals(channelCallCfg.getBizScene()) && "0000".equals(channelCallCfg.getCallIndex()))) {
                SignCardInfoBean signCardInfo = (SignCardInfoBean) GlobalTransUtil.getCacheValue(TransCacheConstant.SIGN_CARD_INFO);
                if (null != signCardInfo) {
                    String signToken;
                    if ("00".equals(channelCallCfg.getBizScene()) || "01".equals(channelCallCfg.getBizScene())) {
                        //本行卡快捷签约，协议号由支付平台生成
                        signToken = signCardInfo.getBankBranchCode().trim() + "|" + DateUtil.getCurrentTimeStamp() + RandomUtil.getRandomInt();
                    } else {
                        //银联无卡快捷支付签约，协议号采用银联返回的协议号
                        cc.rengu.igas.channel.ncqs.facade.result.Result<NcqsAgreePaySignAcqResponse> callResult = (cc.rengu.igas.channel.ncqs.facade.result.Result<NcqsAgreePaySignAcqResponse>) channelResponse;
                        NcqsAgreePaySignAcqResponse ncqsAgreePaySignAcqResponse = callResult.getResult();
                        signToken = signCardInfo.getBankBranchCode().trim() + "|" + ncqsAgreePaySignAcqResponse.getSignNo();
                    }
                    //登记用户及签约信息
                    registerUserAndSignInfo(signToken, fisrtCardSignAndPayRequest.getSignTokenType(), signCardInfo, fisrtCardSignAndPayRequest);
                }
            }
        }
        return transStatusEnum;
    }

    /**
     * 动态解析短信模板生成短信内容
     *
     * @param templateDesc 短信模板内容
     * @return 短信内容
     */
    private String parseSmsTemplateInfo(String templateDesc, String acctNo) {
        StringBuilder stringBuilder = new StringBuilder();
        while (!StringUtil.isEmptyOrNull(templateDesc) && templateDesc.contains("[")) {
            int startIndex = templateDesc.indexOf("[");
            stringBuilder.append(templateDesc, 0, startIndex);
            templateDesc = templateDesc.substring(startIndex + 1);
            int endIndex = templateDesc.indexOf("]");
            stringBuilder.append(acctNo.substring(acctNo.length() - 4));
            templateDesc = templateDesc.substring(endIndex + 1);
        }
        stringBuilder.append(templateDesc);
        return stringBuilder.toString();
    }

    /**
     * 登记用户及签约信息
     *
     * @param signToken                  签约标记号
     * @param signTokenType              签约标记类型
     * @param signCardInfoBean           银行卡签约相关信息
     * @param fisrtCardSignAndPayRequest 请求对象
     * @throws Exception 异常
     */
    private void registerUserAndSignInfo(String signToken, String signTokenType, SignCardInfoBean signCardInfoBean, FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UserInfo userInfo = generateUserInfo(fisrtCardSignAndPayRequest);
        SignAcctInfo signAcctInfo = generateSignAcctInfo(signToken, signTokenType, signCardInfoBean, fisrtCardSignAndPayRequest);
        //签约信息表中的userId和用户表的userId进行关联
        signAcctInfo.setUserId(userInfo.getUserId());

        int iReturnCode;
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppParamConstant.DATABASE_CONF_NODE, AppParamConstant.OLTP_POOL_NAME);
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        /* Step1：开启数据库事务 */
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppParamConstant.OLTP_POOL_NAME);
            dbsUtil = new DbsUtil(dbPoolName);
        }
        dbsUtil.dbsBeginTransaction();
        /* Step2：登记签约信息 */
        SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
        iReturnCode = signAcctInfoMapper.insertSignAcctInfo(signAcctInfo, true);
        if (iReturnCode != 0) {
            dbsUtil.dbsEndTransaction(false);
            throw new BizException(RespCodeEnum.USER_REGISTER_ERROR.getRespCode(), RespCodeEnum.USER_REGISTER_ERROR.getRespDesc());
        }
        /* Step3：登记收银台用户信息 */
        UserService userService = new UserServiceImpl();
        boolean registerFlag = userService.registerUserInfo(userInfo);
        if (!registerFlag) {
            dbsUtil.dbsEndTransaction(false);
            throw new BizException(RespCodeEnum.USER_REGISTER_ERROR.getRespCode(), RespCodeEnum.USER_REGISTER_ERROR.getRespDesc());
        }
        /* Step4：结束数据库事务 */
        dbsUtil.dbsEndTransaction(true);
        /* Step5：将签约用信息信息放到交易缓存中 */
        GlobalTransUtil.setCacheValue(TransCacheConstant.SIGN_ACCT_INFO, signAcctInfo);
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(userInfo.getInstId(), OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.SESSION_EXPIRY_TIMES);
        int sessionExpiryTime = sysParam == null || StringUtil.isEmptyOrNull(sysParam.getParamValue()) ? OpmsParamConstant.SESSION_DEFAULT_TIMES : Integer.parseInt(sysParam.getParamValue());
        RedisUtil.hashSet(fisrtCardSignAndPayRequest.getHeader().getSession(), userInfo.getInstId() + userInfo.getUserId(), JSON.toJSONString(userInfo), sessionExpiryTime);
    }

    /**
     * 生成收银台用户信息
     *
     * @param fisrtCardSignAndPayRequest 请求对象
     * @return 收银台用户信息
     * @throws Exception 异常
     */
    private UserInfo generateUserInfo(FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = fisrtCardSignAndPayRequest.getHeader().getInstId();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        UserInfo userInfo = new UserInfo();
        userInfo.setInstId(fisrtCardSignAndPayRequest.getHeader().getInstId());
        String userInst = instId;
        if (!StringUtil.isEmptyOrNull(fisrtCardSignAndPayRequest.getPlatMchntNo())) {
            MchntService mchntService = new MchntServiceImpl();
            PlatMchntInfo platMchntInfo = mchntService.getPlatMchntInfo(instId, fisrtCardSignAndPayRequest.getPlatMchntNo());
            if (null != platMchntInfo && SignTypeEnum.PLAT_CLASS_SIGN.getSignTypeCode().equals(platMchntInfo.getSignType())) {
                userInst = platMchntInfo.getPlatMchntNo();
            }
        }
        userInfo.setUserInst(userInst);
        String userId = fisrtCardSignAndPayRequest.getUserId();
        if (StringUtil.isEmptyOrNull(userId)) {
            userInfo.setUserId(instId + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8));
        } else {
            userInfo.setUserId(userId);
        }
        //用户加密盐生成规则：当前机构号+8位日期+8为序列号
        userInfo.setTransPasswordSalt(instId + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8));
        userInfo.setUserName(fisrtCardSignAndPayRequest.getCardHoldName());
        userInfo.setMobileNo(fisrtCardSignAndPayRequest.getPhoneNo());
        userInfo.setCertType(fisrtCardSignAndPayRequest.getCertType());
        userInfo.setCertNo(fisrtCardSignAndPayRequest.getCertNo());
        userInfo.setUserStatus(OpmsParamConstant.USER_INFO_USER_STATUS_NORMAL);
        userInfo.setTransPasswordErrorTimes(0);
        return userInfo;
    }

    /**
     * 生成签约信息
     *
     * @param signToken                  签约标记号
     * @param signTokenType              签约标记类型
     * @param signCardInfo               签约账号相关信息
     * @param fisrtCardSignAndPayRequest 请求对象
     * @return 签约信息
     * @throws Exception 异常
     */
    private SignAcctInfo generateSignAcctInfo(String signToken, String signTokenType, SignCardInfoBean signCardInfo, FisrtCardSignAndPayRequest fisrtCardSignAndPayRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UserService userService = new UserServiceImpl();
        SignAcctInfo signAcctInfo = new SignAcctInfo();
        ConvertUtil.convertOutput(signAcctInfo);
        signAcctInfo.setSignToken(signToken);
        signAcctInfo.setSignTokenType(signTokenType);
        signAcctInfo.setSignType(userService.getUserSignType());
        signAcctInfo.setSignInst(userService.getUserSignInst());
        signAcctInfo.setSignAcctType(signCardInfo.getAcctType());
        signAcctInfo.setPayIndex(1);
        signAcctInfo.setSignAcctNo(fisrtCardSignAndPayRequest.getAcctNo());
        signAcctInfo.setReserveMobileNo(fisrtCardSignAndPayRequest.getPhoneNo());
        signAcctInfo.setSignBankNo(signCardInfo.getBankBranchCode());
        signAcctInfo.setSignBankName(signCardInfo.getBankName());
        signAcctInfo.setSignDate(DateUtil.getCurrentDate());
        signAcctInfo.setSignSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        signAcctInfo.setSignExpiryDate("20991231");
        signAcctInfo.setSignStatus(AppParamConstant.YES);
        //获取银行设置的默认限额配置信息
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam singleSysParam = sysParamService.getSysParamInfo(signAcctInfo.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.SINGLE_LIMIT_AMT);
        SysParam daySysParam = sysParamService.getSysParamInfo(signAcctInfo.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.DAY_LIMIT_AMT);
        SysParam noPasswordParam = sysParamService.getSysParamInfo(signAcctInfo.getInstId(), OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.NO_PASSWORD_LIMIT_AMT);
        SysParam authLimitParam = sysParamService.getSysParamInfo(signAcctInfo.getInstId(), OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.AUTH_LIMIT_AMT);
        if (StringUtil.isEmptyOrNull(fisrtCardSignAndPayRequest.getDayLimitAmt()) && null != daySysParam) {
            signAcctInfo.setDayLimitAmt(daySysParam.getParamValue());
        }
        if (StringUtil.isEmptyOrNull(fisrtCardSignAndPayRequest.getSingleLimitAmt()) && null != singleSysParam) {
            signAcctInfo.setDayLimitAmt(singleSysParam.getParamValue());
        }
        if (StringUtil.isEmptyOrNull(fisrtCardSignAndPayRequest.getNoPasswordAmt()) && null != noPasswordParam) {
            signAcctInfo.setNoPasswordAmt(noPasswordParam.getParamValue());
        }
        if (null != authLimitParam) {
            signAcctInfo.setAuthLimitAmt(authLimitParam.getParamValue());
        }
        signAcctInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        signAcctInfo.setSignTokenInst(OpmsParamConstant.DEFAULT_SIGN_TOKEN_INST);
        return signAcctInfo;
    }

    /**
     * 支付失败后/异常统一更新订单状态为支付失败
     *
     * @param userOrderInfo      用户订单信息
     * @param mchntOrderInfoList 商户订单信息
     * @throws Exception 异常
     */
    private void updateOrderInfoFail(UserOrderInfo userOrderInfo, List<MchntOrderInfo> mchntOrderInfoList) throws Exception {
        OrderService orderService = new OrderServiceImpl();
        /* Step1：更新用户订单信息 */
        if (null != userOrderInfo) {
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        }
        /* Step2：更新商户订单信息 */
        if (null != mchntOrderInfoList && !mchntOrderInfoList.isEmpty()) {
            for (MchntOrderInfo mchntOrderInfo : mchntOrderInfoList) {
                mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
                mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            }
        }
        /* Step3：更新订单信息 */
        if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, null)) {
            rglog.error("更新订单表状态失败");
            /*返回结果未知，让前端发起查询*/
            throw new BizException(RespCodeEnum.BIZ_TIMEOUT_ERROR.getRespCode(), RespCodeEnum.BIZ_TIMEOUT_ERROR.getRespDesc());
        }
    }
}
